#pragma once

struct VertexStruct
{
	float x, y, z; 
	float nx, ny, nz;
	DWORD color;     
	float tu, tv; 
};

struct DisplayContext
{
	IDirect3DVertexBuffer8 *ibuffer;
	VertexStruct* buffer;
	VertexStruct* pbuffer;
	int vertexCount;
	int mode;
	int shit3;
};

struct TextureStruct
{
	int target;
	IDirect3DBaseTexture8 *texture;
	int minifilter;
	int mipfilter;
	int magnifilter;
	int addressU;
	int addressV;
};

class MatrixStack:public D3DXMATRIX
{
public:
	MatrixStack():prev(NULL)
	{
		D3DXMatrixIdentity(this);
	}

	//D3DMATRIX mt;
	MatrixStack *prev;
};

class CDXContext
{
public:
	CDXContext(void);
	~CDXContext(void);

	void dispose();
	bool free();
	void reset();
	static CDXContext* create(HWND hDeviceWnd,int width,int height,BOOL bWin);
	bool makeCurrent();

	static void glMaterialfv(int face,int pname,const float *params);
	static void glLightfv(int light, int pname, const float *params);
	static void glDisable(int cap);
	static void glLightModelfv(int params,const float* params);
	static void gluLookAt(double eyex,  double eyey,  double eyez,  double centerx,  double centery,  double centerz,  double upx,  double upy, double upz);
	static void glDepthFunc(int func);
	static void glClearColor(float red,float green,float blue,float alpha);
	static void glClear(DWORD mask);
	static void glEnable(int cap);
	static void glEnableClientState(int array);
	static void glDisableClientState(int array);
	//static void glFrontFace(int mode);
	static void glCullFace(int mode);
	static void glBegin(int mode);
	static void glEnd();
	static void glCallList(DWORD list);
	static void glColor4f(float red,float green,float blue,float alpha);
	static void glNormal3f(float nx,float ny,float nz);
	static void glVertex3f(float x,float y,float z);
	static void glVertexPointer(int size,int type,int stride,const void* pointer);
	static void glNormalPointer(int type,int stride,const void* pointer);
	static void glTexCoordPointer(int size,int type,int stride,const void* pointer);
	static void glDrawElements(int mode,int count,int type,const void* indices);
	static void glMatrixMode(int mode);
	static void glPushMatrix();
	static void glPopMatrix();
	static void glLoadIdentity();
	static void glLoadMatrixf(float *m);
	static void glMultMatrixf(float *m);
	static void glRotatef(float angle,float x,float y,float z);
	static void glScalef(float x,float y,float z);
	static void glTranslatef(float x,float y,float z);
	static void glClearDepth(double depth);
	static void glBlendFunc(int sfactor,int dfactor);
	static void glAlphaFunc(int func,float re);
	static void glDepthMask(BYTE flag);
	static void glPolygonOffset(float factor,float units);
	static void gluPerspective(double fovy,double aspect,double zNear,double zFar);
	static void glBindTexture(int target,DWORD testure);

protected:
	int init(BOOL bWin);
	void initLight();
	void initMaterial();
	static void freeVertex();
	void excuteDisplay(DisplayContext* cont);
	void addDisplayVertex(float x,float y,float z);

	int m_FrontFaceDirection;
	float m_normalX;
	float m_normalY;
	float m_normalZ;
	int m_colorR;
	int m_colorG;
	int m_colorB;
	int m_colorA;
	MatrixStack **m_matrix0;
	MatrixStack *m_matrixModelView;
	MatrixStack *m_matrixProjection;
	MatrixStack *m_matrixTexture;
	float m_fLightPosW;
	float m_fLightSpotCutOff;
	float m_clearColorR;
	float m_clearColorG;
	float m_clearColorB;
	float m_clearColorA;
	float m_clearZ;
	int m_DrawBufferMode;
    float m_textureU;
	float m_textureV;
	BOOL m_bEnableTexture2D;
    BOOL m_bNomalArrayClient;
	int m_NormalPointerType;
	int m_NormalPointerStride;
	void *m_NormalPointerPointer;
	BOOL m_bTextrueCoordArrayClient;
	int m_TexCoordPointerSize;
	int m_TexCoordPointerType;
	int m_TexCoordPointerStride;
	void *m_TexCoordPointerPointer;
	BOOL m_bVertexArrayClient;
	int m_VertexPointerSize;
	int m_VertexPointerType;
	int m_VertexPointerStride;
	void *m_VertexPointerPointer;
	TextureStruct* m_Texture;
	BOOL m_bEnablePolygonOffsetFill;
	float m_PolygonOffsetFactor;
	float m_PolygonOffsetUnits;
	DisplayContext m_DisplayContexts[200];
	int fuck8;
	DisplayContext *m_DisplayContext0;
	HWND m_hDeviceWindow;
	int m_BackBufferWidth;
	int m_BackBufferHeight;
	IDirect3DDevice8* m_device;
	D3DPRESENT_PARAMETERS m_params;
	BOOL m_bWin;
};
